# -*- coding: utf-8 -*-
import json
from pathlib import Path
import numpy

def overlap(x1, w1, x2, w2):
    left = max(x1 - w1 * 0.5, x2 - w2 * 0.5)
    right = min(x1 + w1 * 0.5, x2 + w2 * 0.5)
    return right - left


def iou(box, truth):
    w = overlap(box[0], box[2], truth[0], truth[2])
    h = overlap(box[1], box[3], truth[1], truth[3])
    if (w < 0 or h < 0):
        return 0

    inter_area = w * h
    union_area = box[2] * box[3] + truth[2] * truth[3] - inter_area
    return inter_area * 1.0 / union_area


def sort_key(item):
    return item['bbox'][0]

# from functools import reduce
# def str2float(s):
#     def fn(x,y):
#             return x*10+y
#
#     if "." in s:
#         n = s.index('.')
#         s1=list(map(int,[x for x in s[:n]]))
#         s2=list(map(int,[x for x in s[n+1:]]))
#         return reduce(fn,s1)+reduce(fn,s2)/10**len(s2)
#     else:
#         print("ssss:",s)
#         return float(s)

def get_result_dict(file_path):
    out_dict = {}
    infile = open(file_path, 'r')
    lines = infile.readlines()
    for line in lines:
        line_vec = line.strip().split("\t")
        if len(line_vec) != 4:
            continue
        imgname = line_vec[0]
        clas = line_vec[1]
        conf = line_vec[2]
        tmp_bbox = line_vec[3]
        tmp_bbox = tmp_bbox.strip("[").strip("]")
        bbox = tmp_bbox.split(' ')
        # print("tmp_bbox type:",type(tmp_bbox))
        # print("tmp_bbox:",tmp_bbox)
        # bbox = json.loads(tmp_bbox)
        # print("bbox:",bbox)
        float_bbox = [float(item) for item in bbox if len(item)>0]
        bbox = numpy.array(float_bbox)
        tmpkey = str(clas) + "_" + imgname
        if tmpkey in out_dict:
            out_dict[tmpkey].append([clas, conf, bbox])
        else:
            tmp_list = [[clas, conf, bbox]]
            out_dict[tmpkey] = tmp_list
    print("run end total item:", len(out_dict))
    return out_dict

def get_distance(bbox1,bbox2):

    if (len(bbox1)<4):
        print("bbox1:", bbox1)
        print("bbox2:", bbox2)
    mid1x = bbox1[0]+(bbox1[2]-bbox1[0])*0.5
    mid1y = bbox1[1]+(bbox1[3]-bbox1[1])*0.5
    mid2x = bbox2[0]+(bbox2[2]-bbox2[0])*0.5
    mid2y = bbox2[1]+(bbox2[3]-bbox2[1])*0.5
    dis = pow(mid2x - mid1x, 2) + pow(mid2y - mid1y, 2)
    return dis
def find_closest_bbox(bbox, yitulist):

    mindist = get_distance(bbox,yitulist[0][2])
    minidx = 0
    for i in range(1,len(yitulist)):
        dist = get_distance(bbox,yitulist[i][2])
        if dist < mindist:
            mindist = dist
            minidx = i
    return yitulist[minidx]

def generate_outstr(imgname, nvda_item, yitu_item):
    #item clas, conf, bbox
    outstr = imgname + "\t"
    #图片路径 fp16 置信度	依图int8 置信度	置信度差	fp16 bbox	依图bbox	边界框iou class
    outstr += str(nvda_item[1]) + "\t"
    outstr += str(yitu_item[1]) + "\t"
    dif = float(nvda_item[1]) - float(yitu_item[1])
    outstr += str(dif) + "\t"
    outstr += str(nvda_item[2]) + "\t"
    outstr += str(yitu_item[2]) + "\t"
    tmp_iou = iou(nvda_item[2], yitu_item[2])
    outstr += str(tmp_iou) + "\t" + str(nvda_item[0]) + "\n"
    return outstr


def merge_yitu_nvda(yitu_file, nvda_file, outfilename):
    ###把依图的放到字典里以nvda的为标准去查找，依图的置信度给的阈值低，输出的obj相对多些
    outfile = open(outfilename, 'w')
    yitu_dict = get_result_dict(yitu_file)
    infile = open(nvda_file, 'r')
    lines = infile.readlines()
    count = 0
    not_found_cnt = 0
    for line in lines:
        line_vec = line.strip().split("\t")
        if len(line_vec) != 4:
            continue
        imgname = line_vec[0]
        clas = line_vec[1]
        conf = line_vec[2]
        tmp_bbox = line_vec[3]
        tmp_bbox = tmp_bbox.strip("[").strip("]")
        bbox = tmp_bbox.split(', ')
        float_bbox = [float(item) for item in bbox if len(item) >0]
        # print("tmp_bbox type:",type(tmp_bbox))
        # print("tmp_bbox:",tmp_bbox)
        # bbox = json.loads(tmp_bbox)
        # bbox = numpy.array(bbox)
        # bbox = json.loads(tmp_bbox)
        bbox = numpy.array(float_bbox)
        # print("bbox:",bbox)
        tmpkey = str(clas) + "_" + imgname
        if tmpkey in yitu_dict:
            outitem = find_closest_bbox(bbox, yitu_dict[tmpkey])
            outstr = generate_outstr(imgname, [clas, conf, bbox], outitem)
            outfile.write(outstr)
            count += 1
        else:
            print("key not found in yitu_dict:",tmpkey)
            not_found_cnt += 1
    print("run end total count:",count, "not found cnt:", not_found_cnt)



if __name__ == "__main__":
    yitu_file = "yitu_yolo_result.txt"
    nvda_file = "nvda_yolo_result.txt"
    outfilename = "yitu_nvda_compare_result.txt"
    merge_yitu_nvda(yitu_file, nvda_file, outfilename)

